package chat

import (
	"bufio"
	"encoding/json"
	"fmt"
	chatModel "gxcvu-ai/app/model/chat"
	"io"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
)

type Kimi struct {
	Model string `json:"model"`
}

type KimiRequest struct {
	Model          string    `json:"model"`
	Messages       []Message `json:"messages"`
	Stream         bool      `json:"stream"`
	Temperature    float64   `json:"temperature,omitempty"`
	ResponseFormat struct {
		Type string `json:"type"`
	} `json:"response_format"`
}

type KimiReponse struct {
	Id      string `json:"id"`
	Object  string `json:"object"`
	Created int    `json:"created"`
	Model   string `json:"model"`
	Choices []struct {
		Index int `json:"index"`
		Delta struct {
			Role    string `json:"role,omitempty"`
			Content string `json:"content"`
		} `json:"delta"`
		Logprobs     string `json:"logprobs"`
		FinishReason string `json:"finish_reason"`
	} `json:"choices"`
}

type KimiTokenReponse struct {
	Data struct {
		TotalTokens int64 `json:"total_tokens,omitempty"`
	} `json:"data,omitempty"`
}

//https://api.openai.com/v1/chat/completions

func (e Kimi) NewChat(data []chatModel.Message, c *gin.Context) {
	url := "https://api.moonshot.cn/v1/chat/completions"
	const key = "sk-n8xpCyJK15zkY9raaKqfLUQibpXuvsH0OAcpOseRjMZnwmCh"

	payload := KimiRequest{
		Model:       "moonshot-v1-32k",
		Messages:    formatChatMessage(data),
		Stream:      true,
		Temperature: 0.3,
	}
	payload.ResponseFormat.Type = "text"

	postForm, _ := json.Marshal(payload)
	req, _ := http.NewRequest("POST", url, strings.NewReader(string(postForm)))
	req.Header.Add("Authorization", "Bearer "+key)
	req.Header.Add("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer resp.Body.Close()
	// 转发 SSE 到客户端
	_, ok := c.Writer.(http.Flusher)
	if !ok {
		http.Error(c.Writer, "Streaming unsupported!", http.StatusInternalServerError)
		return
	}
	// 创建一个新的读取器和写入器，用于复制数据
	defer resp.Body.Close()
	reader := bufio.NewReader(resp.Body)
	for {
		line, _, err := reader.ReadLine()
		if err == io.EOF {
			break
		}
		if string(line) == "[DONE]" {
			break
		}

		data := strings.TrimPrefix(string(line), "data:")
		if data == "" {
			continue
		}

		var jsonData KimiReponse
		err = json.Unmarshal([]byte(data), &jsonData)
		if err != nil {
			fmt.Println("Error unmarshaling JSON:", err)
			continue
		}
		chatResp := ChatResponse{
			IsEnd:   jsonData.Choices[0].FinishReason == "stop",
			Result:  jsonData.Choices[0].Delta.Content,
			Id:      jsonData.Id,
			Object:  "assistant",
			Created: jsonData.Created,
			Model:   jsonData.Model,
		}
		c.SSEvent("result", chatResp)
		c.Writer.Flush()
	}

}

func GetTokenCount(messages []Message) int64 {
	const url = "https://api.moonshot.cn/v1/tokenizers/estimate-token-count"
	const key = "sk-n8xpCyJK15zkY9raaKqfLUQibpXuvsH0OAcpOseRjMZnwmCh"

	payload := KimiRequest{
		Model:    "moonshot-v1-32k",
		Messages: messages,
	}

	postForm, _ := json.Marshal(payload)
	req, _ := http.NewRequest("POST", url, strings.NewReader(string(postForm)))
	req.Header.Add("Authorization", "Bearer "+key)
	req.Header.Add("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return 0
	}
	defer resp.Body.Close()
	var jsonData KimiTokenReponse
	err = json.NewDecoder(resp.Body).Decode(&jsonData)
	if err != nil {
		return 0
	}
	return jsonData.Data.TotalTokens
}
